package com.stylefeng.guns.rest.modular.auth.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.aliyuncs.exceptions.ClientException;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.stylefeng.guns.core.base.controller.BaseController;
import com.stylefeng.guns.core.cache.CacheKit;
import com.stylefeng.guns.core.util.AliMsgUtils;
import com.stylefeng.guns.core.util.MD5Util;
import com.stylefeng.guns.rest.Tools.CodeMsg;
import com.stylefeng.guns.rest.Tools.Result;
import com.stylefeng.guns.rest.Util.Md5Util;
import com.stylefeng.guns.rest.common.SystemProperties;
import com.stylefeng.guns.rest.common.annotion.SSO;
import com.stylefeng.guns.rest.common.exception.BizExceptionEnum;
import com.stylefeng.guns.rest.common.persistence.model.DriverInf;
import com.stylefeng.guns.rest.modular.DTO.DriverInfDTO;
import com.stylefeng.guns.rest.modular.auth.controller.dto.AuthRequest;
import com.stylefeng.guns.rest.modular.auth.converter.BaseTransferEntity;
import com.stylefeng.guns.rest.modular.auth.security.impl.Base64SecurityAction;
import com.stylefeng.guns.rest.modular.auth.util.JwtTokenUtil;
import com.stylefeng.guns.rest.modular.auth.validator.IDriverInfService;
import com.stylefeng.guns.rest.modular.auth.validator.IReqValidator;
import com.stylefeng.guns.rest.validater.Insert;
import com.stylefeng.guns.rest.validater.Search;
import com.stylefeng.guns.rest.validater.Update;
import com.stylefeng.guns.rest.validater.Verify;
import com.taobao.api.ApiException;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.MediaType;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/**
 * 请求验证的
 *
 * @author 张亚林
 * @Date 2018/11/12 14:22
 */
@RestController
@RequestMapping("/gunsApi/driver")
@Api(value = "司机端手机验证相关操作", tags = {"司机端手机验证相关操作"})
public class AuthController extends BaseController {
    @Resource
    private IDriverInfService driverInfService;

    @Resource
    private JwtTokenUtil jwtTokenUtil;


  @Resource
    private SystemProperties systemProperties;

    private static  final String TRANSFERCACHE="CONSTANT";

    @Resource(name = "dbValidator")
    private IReqValidator reqValidator;


    @ApiOperation(value = "获取帮助中心电话", notes = "获取帮助中心电话", httpMethod = "POST")
    @PostMapping(value = "/getHelpCenter")
    @SSO
    public Result getHelpCenter(){
        Map<String, Object> map = new LinkedHashMap<>();
        CodeMsg codeMsg=CodeMsg.REQUEST_SUCESS;
        map.put("helpCener",systemProperties.getHelpCenter());
        map.putAll(BeanUtil.beanToMap(codeMsg));
        return Result.success(map);
    }
    @ApiOperation(value = "获取短信登录验证码", notes = "获取短信登录验证码", httpMethod = "POST")
    @PostMapping(value = "/getVerifyCode")
    public Result getVerifyCode(@Validated(value=Search.class)@RequestBody AuthRequest authRequest, BindingResult result)throws ApiException{
        Map<String, Object> map = new LinkedHashMap<>();
        if(result.hasErrors()){
            CodeMsg codeMsg=CodeMsg.BIND_ERROR;
            map.putAll(BeanUtil.beanToMap(codeMsg));
            return  Result.error("参数校验异常,必填参数不能为空!",500101);
        }
        String user=authRequest.getUserName();
        String random=RandomUtil.randomNumbers(4);
        AliMsgUtils.sendDySms(user,random);
        CacheKit.put(TRANSFERCACHE,"code_"+user,random);
        return Result.success("获取短信验证码成功!");
    }

    @ApiOperation(value = "获取司机信息", notes = "获取司机信息", httpMethod = "POST")
    @PostMapping(value = "/getDriverInfo")
    @SSO
    public Result getDriverInfo(){
        String token= this.getHttpServletRequest().getHeader("Authorization").substring(7);
        String user=jwtTokenUtil.getUsernameFromToken(token);
        Wrapper<DriverInf> wrapper=new EntityWrapper<>();
        wrapper.eq("di_phone",user);
        DriverInf driverInf=this.driverInfService.selectOne(wrapper);
        DriverInfDTO dto=new DriverInfDTO();
        if(driverInf!=null){
            BeanUtil.copyProperties(driverInf,dto);
            return Result.success(dto);
        }
        return Result.error("获取司机信息失败",500102);
      }


    @ApiOperation(value = "司机登录验证", notes = "司机登录验证", httpMethod = "POST")
    @PostMapping(value = "${jwt.auth-path}")
    public Result createAuthenticationToken(@Validated(value = Verify.class) @RequestBody AuthRequest authRequest, BindingResult result)throws ClientException{
        Map<String, Object> map = new LinkedHashMap<>();
        if (result.hasErrors()) {
            return Result.error(CodeMsg.REQUEST_ERROR);
        }
        boolean validate =false;
        if(authRequest.getType().equals(0))
            validate = reqValidator.validate(authRequest);
        else{//验证码登录
            String username=authRequest.getUserName();
            if(StringUtils.isNotBlank(username)){
                EntityWrapper<DriverInf> wrapper=new EntityWrapper<>();
                wrapper.eq("di_phone",username);
                DriverInf driverInf=this.driverInfService.selectOne(wrapper);
                if (driverInf==null){
                    return Result.error(CodeMsg.USER_NO_REG.getMessage(),500103);
                }
            }
            String code=CacheKit.get(TRANSFERCACHE,"code_"+username);
       if (StringUtils.equals(code,authRequest.getPassword())){
           validate=true;
       }else{
           CodeMsg codeMsg=CodeMsg.INVALID_KAPTCHA;
           map.putAll(BeanUtil.beanToMap(codeMsg));
           return Result.error(CodeMsg.REQUEST_ERROR.getMessage(),500102);
       }
        }
        if (validate) {
            final String randomKey = jwtTokenUtil.getRandomKey();
            final String token = jwtTokenUtil.generateToken(authRequest.getUserName(), randomKey);
            String jsonString = JSON.toJSONString(authRequest);
            String encode = new Base64SecurityAction().doAction(jsonString);
            String md5 = MD5Util.encrypt(encode + randomKey);
            BaseTransferEntity baseTransferEntity = new BaseTransferEntity();
            baseTransferEntity.setObject(encode);
            baseTransferEntity.setSign(md5);
            CacheKit.put(TRANSFERCACHE,"randomKey_"+authRequest.getUserName(),randomKey);
            CacheKit.put(TRANSFERCACHE,"token_"+authRequest.getUserName(),token);
            return Result.success(token);
        } else {
            return Result.error(BizExceptionEnum.AUTH_REQUEST_ERROR.getMessage(),1003);
        }
    }

    @ApiOperation(value = "登录对象加密", notes = "登录对象加密", httpMethod = "POST")
    @PostMapping(value = "encrypt")
    @SSO
    public Result encrypt(@Validated(value=Update.class)  AuthRequest authRequest,BindingResult result){
        Map<String, Object> map = new LinkedHashMap<>();
        if (result.hasErrors()) {
            return Result.success(CodeMsg.REQUEST_ERROR.getMessage());
            }
            final String randomKey = CacheKit.get(TRANSFERCACHE,"randomKey_"+authRequest.getUserName());
            String jsonString = JSON.toJSONString(authRequest);
            String encode = new Base64SecurityAction().doAction(jsonString);
            String md5 = MD5Util.encrypt(encode + randomKey);
            BaseTransferEntity baseTransferEntity = new BaseTransferEntity();
            baseTransferEntity.setObject(encode);
            baseTransferEntity.setSign(md5);
            String obj= JSONUtil.toJsonStr(baseTransferEntity);
            return  Result.success(obj);
        }

    @ApiOperation(value = "修改密码", notes = "司机端修改密码", httpMethod = "POST")
    @PostMapping(value = "modifyPass")
    public Result modifyPass(@Validated(value = Update.class) @RequestBody AuthRequest authRequest, BindingResult result) {
        String msg="";
        Boolean bool=false;
        if(result.hasErrors()){
            return Result.error(this.getErrors(result));
        }
        String phone=authRequest.getUserName();
        DriverInf newU = new DriverInf();
        newU.setDiPhone(phone);
        DriverInf driverInf=this.driverInfService.selectOne(new EntityWrapper<>(newU));
        if(driverInf==null){
            CodeMsg codeMsg=CodeMsg.USER_NOT_EXSIST;
            return Result.error(codeMsg.getMessage());
        }else{
            if(authRequest.getType().equals(new Integer(0))){//密码修改
                //验证老密码是否正确
                String passwd=authRequest.getPassword();
                passwd=Md5Util.md5(passwd,driverInf.getDiSalt());
                if(StringUtils.equals(passwd,driverInf.getDiPassword())){
                    bool=true;
                }else{
                    msg="密码输入有误!";
                }
            }else{//验证码修改
                String code=CacheKit.get(TRANSFERCACHE,"code_"+authRequest.getUserName());
                if(StringUtils.equals(code,authRequest.getPassword())){
                    bool=true;
                }else{
                    msg="验证码输入有误!";
                }
            }
      if (bool) {
        driverInf.setDiPassword(Md5Util.md5(authRequest.getNpasswd(), driverInf.getDiSalt()));
        driverInf.setDiCheckResult("1");
        Boolean b = driverInf.updateById();
        if (b) {
            msg="更新密码成功！";
           return Result.success(msg);
        } else {
            msg="更新密码失败!";
            return Result.error(msg,1003);
        }
      }else{
          return Result.error(msg,1003);
      }
        }
    }

    @ApiOperation(value = "找回密码", notes = "司机端找回密码", httpMethod = "POST")
    @PostMapping(value = "getPass")
    public Result getPass(@Validated(value = Update.class) @RequestBody AuthRequest authRequest, BindingResult result) {
        String msg="";
        Boolean bool=false;
        if(result.hasErrors()){
            return Result.error("请输入用户手机号!",500101);
        }
        String phone=authRequest.getUserName();
        DriverInf newU = new DriverInf();
        newU.setDiPhone(phone);
        DriverInf driverInf=this.driverInfService.selectOne(new EntityWrapper<>(newU));
        if(driverInf==null){
            CodeMsg codeMsg=CodeMsg.USER_NOT_EXSIST;
            return Result.error(codeMsg.getMessage(),500102);
        }else{
                String code=CacheKit.get(TRANSFERCACHE,"code_"+authRequest.getUserName());
                if(StringUtils.equals(code,authRequest.getPassword())){
                    bool=true;
                }else{
                    msg="验证码输入有误!";
            }
            }
            if (bool) {
                driverInf.setDiPassword(Md5Util.md5(authRequest.getNpasswd(), driverInf.getDiSalt()));
                driverInf.setDiCheckResult("1");
                Boolean b = driverInf.updateById();
                if (b) {
                    msg="找回密码成功,请重新登录！";
                    return Result.success(msg);
                } else {
                    msg="找回密码失败!";
                    return Result.error(msg,1003);
                }
            }else{
                return Result.error(msg,1003);
            }
        }


    /** 新增司机账号 */
  @ApiOperation(value = "手机号注册", notes = "添加司机账号", httpMethod = "POST")
  @PostMapping(value = "/add",produces = MediaType.APPLICATION_JSON_UTF8_VALUE,consumes= MediaType.APPLICATION_JSON_UTF8_VALUE)
  public Result add(@Validated(value = Insert.class)  @RequestBody DriverInf driverInf, BindingResult result) {
      Map<String, Object> map = new LinkedHashMap<>();
      if (result.hasErrors()) {
          CodeMsg codeMsg=CodeMsg.PARAMETER_ISNULL;
          return Result.error(codeMsg.getMessage());
      }
    // 完善账号信息
    // 判断账号是否重复
    DriverInf newU = new DriverInf();
    newU.setDiPhone(driverInf.getDiPhone());
    DriverInf exiDiver = this.driverInfService.selectOne(new EntityWrapper<>(newU));
  
    if (exiDiver != null) {
        CodeMsg codeMsg=CodeMsg.USER_ALREADY_REG;
      return Result.error(codeMsg.getMessage());
    }
    driverInf.setDiSalt(RandomUtil.randomString(8));
    // 添加用户  默认手机号后六位
    String passwd= driverInf.getDiPassword();
    if(StringUtils.isBlank(passwd))
        driverInf.setDiPassword(Md5Util.md5(StringUtils.substring(StringUtils.trimToNull(driverInf.getDiPhone()), -6),driverInf.getDiSalt()));
    else
        driverInf.setDiPassword(Md5Util.md5(StringUtils.trimToNull(passwd),driverInf.getDiSalt()));
    driverInf.setDiCheckResult("1");
    Boolean b = this.driverInfService.insert(driverInf);
    if (b) {
        CodeMsg codeMsg=CodeMsg.REQUEST_SUCESS;
      return Result.success(codeMsg.getMessage());
    } else {
        CodeMsg codeMsg=CodeMsg.REQUEST_ERROR;
      return Result.error(codeMsg.getMessage());
    }
    }

    private Map<String, String> getErrors(BindingResult result) {
               Map<String, String> map = new HashMap<String, String>();
           List<FieldError> list = result.getFieldErrors();
            for (FieldError error : list) {
                System.out.println("error.getField():" + error.getField());
                   System.out.println("error.getDefaultMessage():" + error.getDefaultMessage());
                map.put(error.getField(), error.getDefaultMessage());
        }
                return map;
           }
}
